package com.bicon.botu.account.interceptor;

/**
 * Created by liushujie on 2018-07-04.
 */

import com.baomidou.mybatisplus.toolkit.Sequence;
import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.bicon.botu.account.common.BoTuOperation;
import com.bicon.botu.account.common.RestfulConstans;
import com.bicon.botu.account.common.utils.APILevel;
import com.bicon.botu.account.common.utils.DateUtil;
import com.bicon.botu.account.common.utils.RequestUtil;
import com.bicon.botu.account.common.utils.UserType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器1
 *
 * @author API鉴权拦截器
 */
@Component
public class AuthInterceptor extends HandlerInterceptorAdapter {


    private static final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);

    private static final Sequence sequence = new Sequence();

//    @Autowired
//    SsoSessionsService ssoSessionsService;

//    @Autowired
//    AgencyCheckService agencyCheckService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {


        HandlerMethod handlerMethod = (HandlerMethod) handler;
        //RequestContext.clean();

        String appkey = request.getHeader(RestfulConstans.APPKEY);
        String token = request.getHeader(RestfulConstans.TOKEN);
        String product = request.getHeader(RestfulConstans.PRODUCT);
        String traceId = request.getHeader(RestfulConstans.TRACEID);
        String requestIp = RequestUtil.getRemoteIp(request);
        String userAgent = request.getHeader(RestfulConstans.USER_AGENT);

        String appVersion = request.getHeader(RestfulConstans.APPVERSION);

        String agencyCode = request.getHeader(RestfulConstans.AGENCY_CODE);
        setTraceId(request, traceId);


        StringBuilder logInfo = new StringBuilder();
        logInfo.append("\n**********************************************************");
        logInfo.append("\n* APP_KEY     :" + appkey);
        logInfo.append("\n* TOKEN       :" + token);
        logInfo.append("\n* agencyCode       :" + agencyCode);
        logInfo.append("\n* PRODUCT     :" + product);
        logInfo.append("\n* REQUEST_IP  :" + requestIp);
        logInfo.append("\n* USER_AGENT  :" + userAgent);
        logInfo.append("\n* TRACE_ID    :" + traceId);
        logInfo.append("\n* APPVERSION    :" + appVersion);
        logInfo.append("\n* HANDLER     :" + handlerMethod.getBean().getClass());
        logInfo.append("\n* METHOD      :" + handlerMethod.getMethod().getName());
        logInfo.append("\n* ACCESS_TIME :" + DateUtil.getNow(DateUtil.Y_M_D_HMS));
        logInfo.append("\n**********************************************************");

        logger.info(logInfo.toString());

        return doAuth(handlerMethod, agencyCode, token, appkey, product);
    }


    /**
     * api鉴权
     *
     * @param handlerMethod
     * @param agencyCode
     * @param token
     * @param appKey
     * @param product
     * @return
     * @throws Exception
     */
    private boolean doAuth(HandlerMethod handlerMethod, String agencyCode,
                           String token, String appKey, String product) throws Exception {
        BoTuOperation boTuOperation = handlerMethod.getMethodAnnotation(BoTuOperation.class);
        if (StringUtils.isEmpty(token) && boTuOperation.needAuth()) {
            throw new Exception("请求未包含认证信息.");

        } else if (!boTuOperation.needAuth()) {
            //不需要鉴权的api needAuth为false
            return true;
        }

        //校验appkey @TODO
//        SsoSessionsModel sessionsModel = null;
        if (!StringUtils.isEmpty(token)) {

            //检查商户租期是否到期 这里需要处理
//            if(!agencyCheckService.checkAgencyService(agencyCode))
//            {
//                throw new Exception("服务到期或者服务暂停");
//            }

            //刷新session：判断用户状态，登录信息状态，session是否过期,然后重置session过期时间
//            sessionsModel = ssoSessionsService.refreshSession(agencyCode, token, product);
//            if (sessionsModel == null) {
//                throw new Exception("无效的token");
//            }
//            //用户权限与接口权限验证
//            this.checkUserType(sessionsModel.getUserType(), boTuOperation.ApiLevel());
        }
        //不传token 不处理，api鉴权通过。约定大约规范，此类接口，如注册、登录、忘记密码、商城首页、商品搜索等操作
        return true;
    }


    private void checkUserType(String userTypeStr, APILevel apiLevel) throws Exception {

        UserType userType = UserType.getUserType(userTypeStr);

        if (userType.getValue() < apiLevel.getValue()) {
            throw new Exception("用户权限不够.");
        }
    }


    /**
     * 设置请求的跟踪ID
     *
     * @param traceId
     */
    private void setTraceId(HttpServletRequest request, String traceId) throws Exception {

        if (StringUtils.isEmpty(traceId)) {
            traceId = String.valueOf(sequence.nextId());
        }
        request.setAttribute(RestfulConstans.TRACEID, traceId);

    }


}